package com.plugin.manage.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.plugin.core.model.entity.SysRole;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * 系统角色Mapper接口
 * 
 * @author mark
 * @date 2025-07-28
 */
@Mapper
public interface SysRoleMapper extends BaseMapper<SysRole> {

    /**
     * 根据角色ID查询角色
     */
    @Select("SELECT * FROM sys_role WHERE role_id = #{roleId} AND del_flag = '0'")
    SysRole selectByRoleId(@Param("roleId") Long roleId);

    /**
     * 根据用户ID和角色ID查询角色（通过用户角色关联表）
     */
    @Select("SELECT r.* FROM sys_role r " +
            "INNER JOIN sys_user_role ur ON r.role_id = ur.role_id " +
            "WHERE ur.user_id = #{userId} AND ur.role_id = #{roleId} AND r.del_flag = '0'")
    SysRole selectByUserIdAndRoleId(@Param("userId") Long userId, @Param("roleId") Long roleId);

    /**
     * 分页查询角色列表
     */
    @Select("<script>" +
            "SELECT * FROM sys_role WHERE del_flag = '0' " +
            "<if test='sysRole.roleName != null and sysRole.roleName != \"\"'>" +
            "AND role_name LIKE CONCAT('%', #{sysRole.roleName}, '%') " +
            "</if>" +
            "<if test='sysRole.roleKey != null and sysRole.roleKey != \"\"'>" +
            "AND role_key LIKE CONCAT('%', #{sysRole.roleKey}, '%') " +
            "</if>" +
            "<if test='sysRole.status != null'>" +
            "AND status = #{sysRole.status} " +
            "</if>" +
            "ORDER BY role_sort ASC, create_time DESC " +
            "LIMIT #{offset}, #{limit}" +
            "</script>")
    List<SysRole> selectRoleList(@Param("offset") int offset,
                                 @Param("limit") int limit,
                                 @Param("sysRole") SysRole sysRole);

    /**
     * 查询所有角色
     */
    @Select("SELECT * FROM sys_role WHERE del_flag = '0' ORDER BY role_sort ASC, create_time DESC")
    List<SysRole> selectAllRoles();

    /**
     * 统计角色数量
     */
    @Select("<script>" +
            "SELECT COUNT(*) FROM sys_role WHERE del_flag = '0' " +
            "<if test='sysRole.roleName != null and sysRole.roleName != \"\"'>" +
            "AND role_name LIKE CONCAT('%', #{sysRole.roleName}, '%') " +
            "</if>" +
            "<if test='sysRole.roleKey != null and sysRole.roleKey != \"\"'>" +
            "AND role_key LIKE CONCAT('%', #{sysRole.roleKey}, '%') " +
            "</if>" +
            "<if test='sysRole.status != null'>" +
            "AND status = #{sysRole.status} " +
            "</if>" +
            "</script>")
    int countRoles(@Param("sysRole") SysRole sysRole);

    /**
     * 根据角色名称查询角色（用于检查重复）
     */
    @Select("<script>" +
            "SELECT * FROM sys_role WHERE role_name = #{roleName} AND del_flag = '0' " +
            "<if test='excludeRoleId != null'>" +
            "AND role_id != #{excludeRoleId} " +
            "</if>" +
            "</script>")
    SysRole selectByRoleName(@Param("roleName") String roleName, 
                            @Param("excludeRoleId") Long excludeRoleId);

    /**
     * 根据角色权限字符串查询角色（用于检查重复）
     */
    @Select("<script>" +
            "SELECT * FROM sys_role WHERE role_key = #{roleKey} AND del_flag = '0' " +
            "<if test='excludeRoleId != null'>" +
            "AND role_id != #{excludeRoleId} " +
            "</if>" +
            "</script>")
    SysRole selectByRoleKey(@Param("roleKey") String roleKey, 
                           @Param("excludeRoleId") Long excludeRoleId);

    /**
     * 检查角色名称是否存在
     * 
     * @param roleName 角色名称
     * @param roleId 排除的角色ID
     * @return 数量
     */
    @Select("SELECT COUNT(1) FROM sys_role WHERE role_name = #{roleName} AND del = '0' " +
            "AND (#{roleId} IS NULL OR role_id != #{roleId})")
    int checkRoleNameExists(@Param("roleName") String roleName, @Param("roleId") Long roleId);

    /**
     * 检查角色标识是否存在
     * 
     * @param roleKey 角色标识
     * @param roleId 排除的角色ID
     * @return 数量
     */
    @Select("SELECT COUNT(1) FROM sys_role WHERE role_key = #{roleKey} AND del = '0' " +
            "AND (#{roleId} IS NULL OR role_id != #{roleId})")
    int checkRoleKeyExists(@Param("roleKey") String roleKey, @Param("roleId") Long roleId);


    /**
     * 批量逻辑删除角色
     * 
     * @param roleIds 角色ID列表
     * @return 删除数量
     */
    @Update("<script>" +
            "UPDATE sys_role SET del = '1', updated_time = NOW() WHERE role_id IN " +
            "<foreach collection='roleIds' item='roleId' open='(' separator=',' close=')'>" +
            "#{roleId}" +
            "</foreach>" +
            "</script>")
    int batchLogicDelete(@Param("roleIds") List<Long> roleIds);

    /**
     * 逻辑删除角色
     * 
     * @param roleId 角色ID
     * @return 删除数量
     */
    @Update("UPDATE sys_role SET del = '1', updated_time = NOW() WHERE role_id = #{roleId}")
    int logicDeleteByRoleId(@Param("roleId") Long roleId);
}
